from utils import json_util, macd_util, form_util, date_util


# 1.郑州煤电 01-26 触发加仓 和 入仓 27日大跌 ? 什么技术条件可以避免 验证
# 2.中远海控 01-22 直接触发加仓 然后一直跌 ? 什么技术条件可以避免 验证

# macd高级验证
# 1、MACD上穿0轴，MACD 上穿0轴，又称指数平滑异同平均线上穿0轴，其特征是：
#   MACD翘头向上穿过0轴，由负值变为正值。
#   MACD上穿0轴的图形如图1所示。从技术上来 讲，MACD上穿0轴表示价格的走势开始进入强势，投资者可以看多并做多。
#   MACD上穿0轴是投资者看多的依据，
#   特别是月MACD上穿0，表明价格将有一大段的升幅，投资者可以及时买进。todo 需要后期完善(2) 可用在总体股筛选

# 2、 MACD下穿0轴，又称指数平滑异同平均线下穿0轴，其特征是：
#   MACD弯头向上穿过0轴，由正值变为负值。
#   MACD下穿0轴的图形如图2所示。从技术上说，MACD下穿0轴 表示价格的走势开始进入弱势，投资者要看空做空，在反弹时及时逢高卖出。
#   提醒：MACD下穿0轴是投资者看空的依据，
#   特别是月MACD下穿0轴，表明价格 将有一大段的跌幅，投资者要及时清仓离场。todo 需要后期完善(3)

# macd 由负转正 适时买进 diff>dea 并且 > 0 博取短价抢反弹 建仓  + 并结合其他信息判断大方向买入
# macd 由负转正 适时买进 diff>dea 并且 < 0 博取短价抢反弹 建仓  + 并结合其他信息判断大方向买入
# 3、 MACD 调头向上，又称指数平滑异同平均线调头向上，其特征是：
#  向下移动的DIFF线开始调头向上移动，并且向上穿过DEA线时产生了“黄金交叉”。
#  MACD调头向上既可以发生在正值区域，即在0轴上方运行。出现MACD调整向上，通常表示震荡回调结束，这时投资者可以适时买进
#  MACD调头向上也可以发生在负值区域，即在0轴下方运行。出现MACD调整向上，表示反弹开始，这时投资者可以适时买进，博取短价，即抢反弹

# diff 掉头示警 正值区域 diff向下穿过dea 回避风险观望
# diff 掉头示警 负值区域 diff向下穿过dea 清空
# 4、 MACD 调头向下，又称指数平滑异同平均线调头向下，其特征是：
#  向上移动的DIFF线开始调头向下移动，并且向下穿过DEA线时产生了“死亡交叉”。
#  MACD调头 向下可以发生在正值区域，即在0轴上方运行。出现MACD调整向下，通常表示震荡回调开始，为了回避风险，投资者还是退出观望为好，
#  调头向下也可以发生在负值区域，即在0轴下方运行。出现MACD调整向下，表示反弹结束，这时投资者要果断抛空
#  特别是月MACD调头向下 **** todo 需要后期完善(1)

# 顶背离周期如何确定 5分钟、15分钟、30分钟、60分钟k线 周期太长作为当天的操作指标
# 5、MACD与价格项背离，又称指数平滑异同平均线与价格顶背离，其特征是：
#  价格逐波上涨，但MACD技术指标不是同步上升，而是逐波下跌。
#  MACD与价格顶背离的图形如图7所示。从 技术上来讲，MACD与价格顶背离预示着价格一轮升势已完成，短期内很可能见顶，
#  特别是价格己有大幅拉升后.如果时MACD再出现死亡交叉，则见顶大幅回落的可能性更大。
#  我们可以结合什么是adx指标来进行分析，
#  投资者这时要做好准备离场或先减仓，一旦价格趋势向下，果断清仓。

# 6、 MACD与价格底背离，又称指数平滑异同平均线与价格底背离，其特征是:
#   价格逐波下跌，但MACD指标线不是同步下降，而是逐波走高。
#   MACD与价格底背离的图形如图8所示。从技术上来讲，MACD与价格底背离预示着价格一轮跌势己完成，短期内很可能见底，
#   特别是价格己有大幅下跌后，如果时MACD再出现黄金交叉，则见底回升的可能性更大。投资者这时要做好准备进场，也可以利用少量资金先进场。
#   提醒：价格在高位时，通常出现一次顶背离，就可以确认见顶;而价格在低位时，可能需要出现几次底背离才能确认见底，
#   还要注意，某一时间周期背离，其他时间不背离，这很可能是假背离，如日K线图背离，而周K线图和月K线图不背离。

# 1、MACD 在0轴上方——每发生一次金叉，股价将创新高
# 2、MACD 在0轴下方——每发生一次死叉，股价将创新低
# 3、MACD 在0轴上方——金叉属于上升趋势多头行情,可低吸高抛到顶背离
# 4、MACD 在0轴下方——金叉属于下降趋势反弹行情,一直到上0轴才参与
# 5、MACD 在0轴上方——金叉死叉次数越多越好、牛股
# 6、MACD 在0轴下方——金叉死叉次数越多越差、熊股
# 7、MACD 将金不金 ——绿柱二次反身向下、必跌

#  评分 按照评分购买 总分100 总分 九档

# 大众评分 只有加分项目 没有不做评分 根据触发的时间长短评分
def common_exam(data):
    data['score'] = 0
    data['total_score'] = 0
    data['score_info'] = {'score': 0, 'msg': '', 'exam_time': date_util.get_timestamp_now()}
    # macd 总分40
    data = exam_macd(data)
    # 用户评分等级划分
    data = score_level(data)
    return data


# macd 积分系统
def exam_all(data):
    # macd 线评分
    score_info = {'score': 0, 'trend': 0, 'msg': ''}
    data['score_info'] = score_info
    data = exam_ave(data)  # 均线评分
    data = exam_macd(data)  # macd 评分
    # data = sl_monitor(data)  # 实际应用评分
    return score_level(data)


# macd 考试 40分
def exam_macd(data):
    rq = data['rq']
    code = data['code']
    rt_price = data['rt_price']
    ave5 = data['ave5']
    ave10 = data['ave10']
    macd_list = macd_util.get_macd_with_time(code, 3, rq, rt_price)
    if not isinstance(macd_list, list) or len(macd_list) < 3:
        return data
    macd_info1 = json_util.info_to_json(macd_list[0])
    macd_info2 = json_util.info_to_json(macd_list[1])
    macd_info3 = json_util.info_to_json(macd_list[2])
    dif1 = macd_info1['EMA12'] - macd_info1['EMA26']
    dif2 = macd_info2['EMA12'] - macd_info2['EMA26']
    dif3 = macd_info3['EMA12'] - macd_info3['EMA26']
    macd1 = macd_info1['macd']
    macd2 = macd_info2['macd']
    macd3 = macd_info3['macd']
    dea1 = macd_info1['DEA']
    dea2 = macd_info2['DEA']

    dif_form = form_util.thr_form([dif1, dif2, dif3])
    dif_form2 = form_util.zero_form(dif1, dif2)
    dea_form2 = form_util.zero_form(dea1, dea2)
    macd_form = macd_util.macd_form(macd_list)
    macd_form2 = form_util.zero_form(macd1, macd2)
    score_info = data['score_info']
    score_info['dif_form'] = dif_form
    score_info['macd_form2'] = macd_form2
    score_info['dea_form2'] = dea_form2
    score_info['dif_form2'] = dif_form2
    score_info['macd_form'] = macd_form
    data['macd'] = macd_form

    score = score_info['score']
    msg = score_info['msg']
    msg += ',macd_form' + macd_form + ',macd_form2' + macd_form2
    msg += ',dif_form' + dif_form + ',dif_form2' + dif_form2
    # macd_form ^, macd_form2L, dif_form /, dif_form2L 青铜
    # macd_form /, macd_form2L, dif_form /, dif_form2L 黄金
    # 最高分20 最低分0
    if macd_form == '/' and macd_form2 == 'T':
        if macd1 > -0.1:
            score += 20
        else:
            score += 10
    elif macd_form == '/' and macd_form2 == '/':
        score += 20
    elif macd_form == '/' and macd_form2 == 'L':
        if macd1 > 0.3:
            score += 5
        else:
            score += 10
    elif macd_form == 'v' and macd_form2 == '/':
        score += 20
    elif macd_form == 'v' and macd_form2 == 'T':
        if macd1 > -0.1:
            score += 10
        else:
            score += 5
    elif macd_form == 'v' and macd_form2 == 'L':
        if macd1 > 0.3:
            score += 5
        else:
            score += 10
    # 特殊情况1 将破未破
    elif macd_form == '^' and macd_form2 == 'L':
        if macd1 > macd3 and ave10 < rt_price < ave5:
            score += 5

    # dif 20分 最低0
    if dif_form == '/':
        if dif_form2 == 'T':
            if dif1 >= -2:
                score += 10
            else:
                score += 5
        elif dif_form2 == '/':
            score += 20
        elif dif_form2 == 'L' and dea_form2 == '/':
            score += 15
        elif dif_form2 == 'L':
            if dif1 < 1:
                score += 15
            else:
                score += 5
    elif dif_form == 'v':
        if dif_form2 == 'T':
            if dif1 >= -2:
                score += 10
            else:
                score += 5
        elif dif_form2 == '/':
            score += 20
        elif dif_form2 == 'L':
            if dif1 < 1:
                score += 15
            else:
                score += 5

    score_info['score'] = score
    score_info['msg'] = msg
    data['score_info'] = score_info
    data['total_score'] = data['total_score'] + 40
    return data


# 均线评分 50
def exam_ave(data):
    rt_price = data['rt_price']
    ave5 = data['ave5']
    ave10 = data['ave10']
    flag5 = data['flag5']
    flag10 = data['flag10']
    score_info = data['score_info']
    score = score_info['score']
    trend = score_info['trend']
    msg = score_info['msg']
    # (1) 突破十日线 and macd形态多头 全仓买入
    # (2) 突破5日均线,未突破10日均线,macd多头形态 半仓买入
    # (3) 跌破十日线 and macd形态空头 清仓卖出
    # (4) 跌破5日均线,未跌破10日线,macd空头形态 减半仓
    if rt_price > ave10:
        msg += '突破十日线'
        score += 50
        trend += 80
    elif rt_price > ave5:
        msg += '突破五日线'
        score += 25
        trend += 80
    elif rt_price < ave10:
        msg += '跌破十日线'
        score += 0
        trend -= 80
    elif rt_price < ave5:
        msg += '跌破五日线'
        score += 25
        trend -= 80
    else:
        print('无均线触发')
    score_info['score'] = score
    score_info['msg'] = msg
    data['score_info'] = score_info
    return data


# 评分等级划分
def score_level(data):
    score_info = data['score_info']
    total_score = data['total_score']
    score = score_info['score']
    if total_score == 0:
        score = 0
    else:
        score = round((score / total_score) * 100, 2)
    # 王者 星耀 钻石 铂金 黄金 白银 青铜
    if 90 < score <= 100:
        score_info['level'] = '9-国服大神'
    elif 70 < score <= 90:
        score_info['level'] = '8-荣耀王者'
    elif 70 < score <= 80:
        score_info['level'] = '7-王者'
    elif 60 < score <= 70:
        score_info['level'] = '6-星耀'
    elif 50 < score <= 60:
        score_info['level'] = '5-钻石'
    elif 40 < score <= 50:
        score_info['level'] = '4-铂金'
    elif 30 < score <= 40:
        score_info['level'] = '3-黄金'
    elif 20 < score <= 30:
        score_info['level'] = '2-白银'
    elif 10 < score <= 20:
        score_info['level'] = '1-青铜'
    elif score <= 10:
        score_info['level'] = '0-黑铁'
    return data


# 实际遇到的雷,排雷
def sl_monitor(data):
    ave_flag = data['ave_flag']
    score_info = data['score_info']
    dif_form = score_info['dif_form']
    macd_form2 = score_info['macd_form2']
    dea_form2 = score_info['dea_form2']
    dif_form2 = score_info['dif_form2']
    msg = score_info['msg']
    score = score_info['score']
    # 实例监控 买入避坑1 - 中远海控20210122
    if ave_flag == 1:
        if (macd_form2 == 'T' or macd_form2 == '\\') and (dif_form == '\\'):  # 出现过死亡交叉
            score_info['score'] = 0
            score_info['dif_form'] = score_info
    # 实例监控 买入避坑1 - 郑州煤电20210126
    return data


if __name__ == '__main__':
    exam_macd({})
